package cn.edu.baiyunu.myapplication.ui.edit

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.net.Uri
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import cn.edu.baiyunu.myapplication.data.model.PhotoSpec
import cn.edu.baiyunu.myapplication.data.repository.PhotoRepository
import cn.edu.baiyunu.myapplication.data.db.entity.PhotoRecord
import cn.edu.baiyunu.myapplication.utils.BitmapUtils
import cn.edu.baiyunu.myapplication.utils.ImageUtils
import cn.edu.baiyunu.myapplication.utils.MODNetProcessor
import cn.edu.baiyunu.myapplication.utils.MessageType
import cn.edu.baiyunu.myapplication.utils.StorageHelper
import cn.edu.baiyunu.myapplication.utils.TFLiteImageProcessor
import cn.edu.baiyunu.myapplication.utils.showMessage
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileOutputStream
import java.text.SimpleDateFormat
import java.util.Locale
import android.app.Application
import kotlinx.coroutines.delay

/**
 * 编辑页面的ViewModel，用于处理图像编辑逻辑
 * 实现了图像美化功能和人像抠图功能
 */
class EditViewModel(
    private val context: Context,
    private val photoRepository: cn.edu.baiyunu.myapplication.data.repository.PhotoRepository? = null
) : ViewModel() {
    
    // MODNet处理器
    private val modNetProcessor = MODNetProcessor(context)
    
    // 处理状态
    private val _isProcessing = MutableStateFlow(false)
    val isProcessing: StateFlow<Boolean> = _isProcessing.asStateFlow()
    
    // 当前编辑的图片
    private val _currentBitmap = MutableLiveData<Bitmap?>()
    val currentBitmap: LiveData<Bitmap?> = _currentBitmap
    
    // 原始图片（用于重置）
    private var originalBitmap: Bitmap? = null
    
    // 人像抠图相关
    private var portraitMask: Bitmap? = null
    private var portraitWithTransparentBg: Bitmap? = null
    
    // 是否已经执行过抠图
    private val _portraitExtracted = MutableStateFlow(false)
    val portraitExtracted: StateFlow<Boolean> = _portraitExtracted.asStateFlow()
    
    // 背景颜色选择
    private val _selectedBgColor = MutableStateFlow(0xFF0078D7.toInt()) // 默认蓝色背景
    val selectedBgColor: StateFlow<Int> = _selectedBgColor.asStateFlow()
    
    // 多背景色选择
    private val _selectedBgColors = MutableStateFlow<Set<Int>>(setOf(0xFF0078D7.toInt()))
    val selectedBgColors: StateFlow<Set<Int>> = _selectedBgColors.asStateFlow()
    
    // 当前激活的标签
    private val _activeTab = MutableStateFlow(EditTab.PORTRAIT_MATTING)
    val activeTab: StateFlow<EditTab> = _activeTab.asStateFlow()
    
    // 裁剪缩放相关
    private val _scale = MutableStateFlow(1f)
    val scale: StateFlow<Float> = _scale.asStateFlow()
    
    // 图片手势变换相关
    private val _gestureScale = MutableStateFlow(1f)
    val gestureScale: StateFlow<Float> = _gestureScale.asStateFlow()
    
    private val _offsetX = MutableStateFlow(0f)
    val offsetX: StateFlow<Float> = _offsetX.asStateFlow()
    
    private val _offsetY = MutableStateFlow(0f)
    val offsetY: StateFlow<Float> = _offsetY.asStateFlow()
    
    // 证件照尺寸相关
    private val _availablePhotoSpecs = MutableStateFlow<List<cn.edu.baiyunu.myapplication.data.model.PhotoSpec>>(emptyList())
    val availablePhotoSpecs: StateFlow<List<cn.edu.baiyunu.myapplication.data.model.PhotoSpec>> = _availablePhotoSpecs.asStateFlow()
    
    private val _selectedPhotoSpec = MutableStateFlow<cn.edu.baiyunu.myapplication.data.model.PhotoSpec?>(null)
    val selectedPhotoSpec: StateFlow<cn.edu.baiyunu.myapplication.data.model.PhotoSpec?> = _selectedPhotoSpec.asStateFlow()
    
    // 参考画布和实际画布
    private val _referenceCanvasSpec = MutableStateFlow<cn.edu.baiyunu.myapplication.data.model.PhotoSpec?>(null)
    val referenceCanvasSpec: StateFlow<cn.edu.baiyunu.myapplication.data.model.PhotoSpec?> = _referenceCanvasSpec.asStateFlow()
    
    private val _actualCanvasSpec = MutableStateFlow<cn.edu.baiyunu.myapplication.data.model.PhotoSpec?>(null)
    val actualCanvasSpec: StateFlow<cn.edu.baiyunu.myapplication.data.model.PhotoSpec?> = _actualCanvasSpec.asStateFlow()
    
    // 画布尺寸比例 (参考画布相对于实际画布的放大比例，默认1.5倍)
    private val _canvasRatio = MutableStateFlow(1.5f)
    val canvasRatio: StateFlow<Float> = _canvasRatio.asStateFlow()
    
    // 是否显示参考画布边界
    private val _showReferenceCanvasBorder = MutableStateFlow(true)
    val showReferenceCanvasBorder: StateFlow<Boolean> = _showReferenceCanvasBorder.asStateFlow()
    
    // 全屏模式状态
    private val _isFullScreenMode = MutableStateFlow(false)
    val isFullScreenMode: StateFlow<Boolean> = _isFullScreenMode.asStateFlow()
    
    // 图片是否超出实际画布
    private val _isImageExceedCanvas = MutableStateFlow(false)
    val isImageExceedCanvas: StateFlow<Boolean> = _isImageExceedCanvas.asStateFlow()
    
    // DPI设置选项
    private val _selectedDpi = MutableStateFlow(300f) // 默认300DPI
    val selectedDpi: StateFlow<Float> = _selectedDpi.asStateFlow()
    
    // 可用的DPI选项
    private val _availableDpiOptions = MutableStateFlow(listOf(72f, 150f, 300f, 600f)) 
    val availableDpiOptions: StateFlow<List<Float>> = _availableDpiOptions.asStateFlow()
    
    // 是否显示预览窗口
    private val _showPreview = MutableStateFlow(false)
    val showPreview: StateFlow<Boolean> = _showPreview.asStateFlow()
    
    // 预览图片
    private val _previewBitmap = MutableLiveData<Bitmap?>()
    val previewBitmap: LiveData<Bitmap?> = _previewBitmap
    
    // 批量处理选项 (简化版，仅用于UI展示)
    private val _batchProcessEnabled = MutableStateFlow(false)
    val batchProcessEnabled: StateFlow<Boolean> = _batchProcessEnabled.asStateFlow()
    
    private val _multiBackgroundEnabled = MutableStateFlow(false)
    val multiBackgroundEnabled: StateFlow<Boolean> = _multiBackgroundEnabled.asStateFlow()
    
    init {
        // 初始化MODNet模型
        viewModelScope.launch(Dispatchers.IO) {
            modNetProcessor.initialize()
        }
        
        // 加载可用的证件照规格
        loadPhotoSpecs()
    }
    
    /**
     * 加载证件照规格列表
     */
    private fun loadPhotoSpecs() {
        _availablePhotoSpecs.value = cn.edu.baiyunu.myapplication.data.model.PhotoSpecProvider.getAllSpecs()
    }
    
    /**
     * 选择证件照规格
     * 修改为：选择后自动应用规格并更新画布
     */
    fun selectPhotoSpec(spec: cn.edu.baiyunu.myapplication.data.model.PhotoSpec) {
        _selectedPhotoSpec.value = spec
        _actualCanvasSpec.value = spec // 立即更新实际画布规格
        
        // 重新计算参考画布尺寸
        calculateReferenceCanvasSpec(spec)
        
        // 添加操作提示
        showMessage("已选择「${spec.name}」规格，画布已自动更新", MessageType.INFO)
        
        // 立即通知UI更新
        viewModelScope.launch {
            // 短暂延迟确保状态更新
            delay(100)
            // 强制显示参考画布边框
            _showReferenceCanvasBorder.value = true
            
            // 自动应用选中的规格 - 直接执行applySelectedSpec的核心逻辑
            _isProcessing.value = true
            
            val bitmap = _currentBitmap.value ?: return@launch
            
            try {
                // 计算目标尺寸（像素）
                val dpi = _selectedDpi.value
                val mmToInch = 0.0393701f
                
                val targetWidthPixels = (spec.width * mmToInch * dpi).toInt()
                val targetHeightPixels = (spec.height * mmToInch * dpi).toInt()
                
                // 创建调整后的图像
                val result = withContext(Dispatchers.Default) {
                    // 计算缩放比例
                    val originalWidth = bitmap.width
                    val originalHeight = bitmap.height
                    
                    val widthRatio = targetWidthPixels.toFloat() / originalWidth
                    val heightRatio = targetHeightPixels.toFloat() / originalHeight
                    
                    // 选择较小的比例，确保图像完全适合目标尺寸
                    val scaleFactor = minOf(widthRatio, heightRatio)
                    
                    // 计算缩放后的尺寸
                    val scaledWidth = (originalWidth * scaleFactor).toInt()
                    val scaledHeight = (originalHeight * scaleFactor).toInt()
                    
                    // 检查是否需要进行扩展 - 缩放后的尺寸比目标尺寸小5%以上
                    val needsExpansion = scaledWidth < targetWidthPixels * 0.95f || scaledHeight < targetHeightPixels * 0.95f
                    
                    // 初始化TFLite处理器
                    val tfLiteProcessor = TFLiteImageProcessor(context)
                    try {
                        Log.d("EditViewModel", "初始化TFLite处理器")
                        tfLiteProcessor.initialize()
                    } catch (e: Exception) {
                        Log.e("EditViewModel", "TFLite处理器初始化失败: ${e.message}", e)
                    }
                    
                    var resultBitmap: Bitmap
                    
                    // 先缩放图像
                    val scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true)
                    
                    // 使用等比例缩放方法调整大小
                    try {
                        Log.d("EditViewModel", "使用等比例调整图像")
                        // 应用等比例调整
                        val expandedBitmap = tfLiteProcessor.expandImage(scaledBitmap, targetWidthPixels, targetHeightPixels)
                        
                        if (expandedBitmap != null) {
                            Log.d("EditViewModel", "等比例调整成功")
                            resultBitmap = expandedBitmap
                        } else {
                            Log.w("EditViewModel", "等比例调整失败，使用增强型放大算法")
                            // 判断是否需要放大
                            val isUpscaling = targetWidthPixels > bitmap.width * 1.1f || targetHeightPixels > bitmap.height * 1.1f
                            
                            if (isUpscaling) {
                                // 使用增强型放大方法
                                resultBitmap = tfLiteProcessor.superResolutionScaling(
                                    scaledBitmap,
                                    targetWidthPixels,
                                    targetHeightPixels
                                )
                                Log.d("EditViewModel", "应用增强型放大算法成功")
                            } else {
                                resultBitmap = createStandardResizedBitmap(
                                    bitmap,
                                    scaledWidth,
                                    scaledHeight,
                                    targetWidthPixels,
                                    targetHeightPixels
                                )
                            }
                        }
                    } catch (e: Exception) {
                        Log.e("EditViewModel", "等比例调整过程中出错: ${e.message}", e)
                        // 出错时使用标准方法
                        resultBitmap = createStandardResizedBitmap(
                            bitmap,
                            scaledWidth,
                            scaledHeight,
                            targetWidthPixels,
                            targetHeightPixels
                        )
                    }
                    
                    // 释放资源
                    if (scaledBitmap != bitmap) {
                        scaledBitmap.recycle()
                    }
                    tfLiteProcessor.close()
                    
                    resultBitmap
                }
                
                // 更新当前图像和预览图像
                _currentBitmap.postValue(result)
                
                // 将已选择的规格设置为已确认规格
                _actualCanvasSpec.value = spec
                
                // 生成预览图
                generatePreview(false)
                
                // 重置变换
                resetGestureTransformation()
                
            } catch (e: Exception) {
                Log.e("EditViewModel", "自动应用规格时出错", e)
                showMessage("应用规格时出错：${e.message}", MessageType.ERROR)
            } finally {
                _isProcessing.value = false
            }
        }
    }
    
    /**
     * 计算参考画布规格 - 基于实际画布尺寸
     */
    private fun calculateReferenceCanvasSpec(actualSpec: cn.edu.baiyunu.myapplication.data.model.PhotoSpec) {
        // 使用PhotoSpec的伴生对象方法创建参考画布规格
        val referenceSpec = cn.edu.baiyunu.myapplication.data.model.PhotoSpec.createReferenceCanvas(
            actualSpec, 
            _canvasRatio.value
        )
        
        _referenceCanvasSpec.value = referenceSpec
        Log.d("EditViewModel", "创建参考画布: ${referenceSpec.width}x${referenceSpec.height}mm, 基于实际画布: ${actualSpec.width}x${actualSpec.height}mm")
    }
    
    /**
     * 设置画布比例
     */
    fun setCanvasRatio(ratio: Float) {
        if (ratio > 1.0f && ratio <= 3.0f) {
            _canvasRatio.value = ratio
            
            // 如果已选择规格，重新计算参考画布
            val actualSpec = _actualCanvasSpec.value
            if (actualSpec != null) {
                calculateReferenceCanvasSpec(actualSpec)
                
                // 确保UI更新
                viewModelScope.launch {
                    delay(50) // 短暂延迟确保状态更新
                    _showReferenceCanvasBorder.value = true // 强制显示参考画布边框以触发重绘
                }
                
                showMessage("参考画布比例已更新: ${ratio}x", MessageType.INFO)
            }
        } else {
            showMessage("画布比例必须大于1.0且不超过3.0", MessageType.WARNING)
        }
    }
    
    /**
     * 切换参考画布边界显示
     */
    fun toggleReferenceCanvasBorder() {
        _showReferenceCanvasBorder.value = !_showReferenceCanvasBorder.value
    }
    
    /**
     * 生成预览图 - 与saveEditedImage保持完全一致的计算方式
     * @param showPreviewWindow 是否在生成预览后自动显示预览窗口
     */
    fun generatePreview(showPreviewWindow: Boolean = true) {
        viewModelScope.launch {
            val spec = _selectedPhotoSpec.value ?: return@launch
            val currentBmp = _currentBitmap.value ?: return@launch
            
            try {
                _isProcessing.value = true
                showMessage("正在生成${spec.name}预览，请稍候...", MessageType.INFO)
                
                // 计算目标尺寸（像素）- 与saveEditedImage完全一致
                val dpi = _selectedDpi.value
                val mmToInch = 0.0393701f
                val targetWidthPixels = (spec.width * mmToInch * dpi).toInt()
                val targetHeightPixels = (spec.height * mmToInch * dpi).toInt()
                
                Log.d("EditViewModel", "预览图 - 规格: ${spec.name}, 尺寸: ${targetWidthPixels}x${targetHeightPixels} 像素, DPI: $dpi")
                
                // 计算当前参考画布尺寸（如果存在）- 与saveEditedImage一致
                val referenceSpec = _referenceCanvasSpec.value
                val canvasRatio = if (referenceSpec != null) {
                    referenceSpec.width / spec.width
                } else {
                    1.5f // 默认参考画布是实际画布的1.5倍
                }
                
                // 计算参考画布大小（像素）- 与saveEditedImage一致
                val referenceWidthPixels = if (referenceSpec != null) {
                    (referenceSpec.width * mmToInch * dpi).toInt()
                } else {
                    targetWidthPixels
                }
                val referenceHeightPixels = if (referenceSpec != null) {
                    (referenceSpec.height * mmToInch * dpi).toInt()
                } else {
                    targetHeightPixels
                }
                
                // 计算实际画布相对于参考画布的中心位置偏移 - 与saveEditedImage一致
                val canvasOffsetX = (referenceWidthPixels - targetWidthPixels) / 2
                val canvasOffsetY = (referenceHeightPixels - targetHeightPixels) / 2
                
                // 记录缩放和偏移的关系 - 与saveEditedImage一致
                Log.d("EditViewModel", "预览图 - 参考画布比例: ${canvasRatio}x, 参考画布像素: ${referenceWidthPixels}x${referenceHeightPixels}, 实际画布像素: ${targetWidthPixels}x${targetHeightPixels}")
                
                // 与saveEditedImage使用完全相同的裁剪逻辑生成预览图
                val previewBitmap = withContext(Dispatchers.Default) {
                    try {
                        // ===== 使用与saveEditedImage相同的裁剪算法 =====
                        Log.d("EditViewModel", "预览图 - 使用新的裁剪算法处理图像")
                        
                        // 1. 获取用户的缩放和偏移信息
                        val userScale = _gestureScale.value
                        val userOffsetX = _offsetX.value
                        val userOffsetY = _offsetY.value
                        
                        Log.d("EditViewModel", "预览图 - 用户缩放: $userScale, 偏移: X=$userOffsetX, Y=$userOffsetY")
                        
                        // 2. 获取原图尺寸
                        val originalWidth = currentBmp.width
                        val originalHeight = currentBmp.height
                        
                        // 3. 创建目标输出图像，大小为证件照规格的像素尺寸
                        val resultBitmap = Bitmap.createBitmap(targetWidthPixels, targetHeightPixels, Bitmap.Config.ARGB_8888)
                        val canvas = Canvas(resultBitmap)
                        // 不自动填充背景色，保持透明背景
                        // canvas.drawColor(_selectedBgColor.value)
                        
                        // 限制绘制区域为画布大小，超出的部分不显示
                        canvas.clipRect(0f, 0f, targetWidthPixels.toFloat(), targetHeightPixels.toFloat())
                        
                        // 4. 计算原始图像中实际显示在屏幕中心的那部分内容的位置
                        // 先计算显示区域（屏幕）的中心点
                        val displayCenterX = originalWidth / 2f
                        val displayCenterY = originalHeight / 2f
                        
                        // 再计算缩放后的图像相对于显示区域中心的偏移
                        // 如果用户向右拖动图像(offsetX为正)，实际裁剪区域应该向左移
                        val effectiveCenterX = (displayCenterX - userOffsetX / userScale)
                        val effectiveCenterY = (displayCenterY - userOffsetY / userScale)
                        
                        // 5. 根据中心点和目标尺寸计算在原图中需要裁剪的区域
                        // 目标区域在原图中的尺寸，需要考虑用户的缩放因素
                        val cropWidthInOriginal = targetWidthPixels / userScale
                        val cropHeightInOriginal = targetHeightPixels / userScale
                        
                        // 计算在原图上的裁剪区域边界
                        val cropLeftInOriginal = (effectiveCenterX - cropWidthInOriginal / 2).toInt().coerceAtLeast(0)
                        val cropTopInOriginal = (effectiveCenterY - cropHeightInOriginal / 2).toInt().coerceAtLeast(0)
                        val cropRightInOriginal = (cropLeftInOriginal + cropWidthInOriginal).toInt().coerceAtMost(originalWidth)
                        val cropBottomInOriginal = (cropTopInOriginal + cropHeightInOriginal).toInt().coerceAtMost(originalHeight)
                        
                        // 6. 实际可以裁剪的区域大小
                        val effectiveCropWidth = cropRightInOriginal - cropLeftInOriginal
                        val effectiveCropHeight = cropBottomInOriginal - cropTopInOriginal
                        
                        Log.d("EditViewModel", "预览图 - 原图尺寸: ${originalWidth}x${originalHeight}")
                        Log.d("EditViewModel", "预览图 - 目标尺寸: ${targetWidthPixels}x${targetHeightPixels}")
                        Log.d("EditViewModel", "预览图 - 裁剪区域(原图坐标系): Left=$cropLeftInOriginal, Top=$cropTopInOriginal, " +
                              "Right=$cropRightInOriginal, Bottom=$cropBottomInOriginal")
                        Log.d("EditViewModel", "预览图 - 实际裁剪尺寸: ${effectiveCropWidth}x${effectiveCropHeight}")
                        
                        // 7. 计算裁剪区域在目标图像上的位置 (居中)
                        val dstLeft = (targetWidthPixels - effectiveCropWidth * userScale) / 2
                        val dstTop = (targetHeightPixels - effectiveCropHeight * userScale) / 2
                        val dstRight = dstLeft + effectiveCropWidth * userScale
                        val dstBottom = dstTop + effectiveCropHeight * userScale
                        
                        // 8. 直接从原图裁剪，然后缩放绘制到结果图像上
                        val srcRect = android.graphics.Rect(
                            cropLeftInOriginal,
                            cropTopInOriginal,
                            cropRightInOriginal,
                            cropBottomInOriginal
                        )
                        
                        val dstRect = android.graphics.RectF(
                            dstLeft,
                            dstTop,
                            dstRight,
                            dstBottom
                        )
                        
                        // 9. 绘制裁剪后的图像到结果图像上
                        Log.d("EditViewModel", "预览图 - 绘制区域: Left=$dstLeft, Top=$dstTop, Right=$dstRight, Bottom=$dstBottom")
                        
                        // 使用原图直接绘制，使用高品质绘制参数
                        val paint = android.graphics.Paint().apply {
                            isFilterBitmap = true
                            isAntiAlias = true
                        }
                        
                        // 严格裁剪，只绘制实际画布(绿色框)内的内容
                        // 这里不使用drawBitmap的缩放绘制，改为先裁剪原图，再精确绘制
                        val croppedBitmap = Bitmap.createBitmap(
                            currentBmp,
                            cropLeftInOriginal,
                            cropTopInOriginal,
                            effectiveCropWidth,
                            effectiveCropHeight
                        )
                        
                        // 将裁剪后的图像缩放到目标大小
                        val finalCroppedBitmap = Bitmap.createScaledBitmap(
                            croppedBitmap,
                            targetWidthPixels,
                            targetHeightPixels,
                            true
                        )
                        
                        // 直接将缩放后的裁剪图像绘制到画布中心
                        canvas.drawBitmap(finalCroppedBitmap, 0f, 0f, paint)
                        
                        // 回收临时创建的位图
                        if (croppedBitmap != currentBmp) {
                            croppedBitmap.recycle()
                        }
                        if (finalCroppedBitmap != croppedBitmap) {
                            finalCroppedBitmap.recycle()
                        }
                        
                        resultBitmap
                    } catch (e: Exception) {
                        Log.e("EditViewModel", "预览图 - 处理失败: ${e.message}", e)
                        e.printStackTrace()
                        
                        // 回退到标准预览方法
                        createStandardPreviewBitmap(currentBmp, currentBmp.width, currentBmp.height, targetWidthPixels, targetHeightPixels)
                    }
                }
                
                _previewBitmap.value = previewBitmap
                
                // 仅在需要时显示预览窗口
                if (showPreviewWindow) {
                    _showPreview.value = true
                }
                
                _isProcessing.value = false
                
            } catch (e: Exception) {
                Log.e("EditViewModel", "生成预览图失败: ${e.message}")
                _isProcessing.value = false
                showMessage("生成预览图失败", MessageType.ERROR)
            }
        }
    }
    
    /**
     * 创建标准预览位图
     */
    private fun createStandardPreviewBitmap(
        bitmap: Bitmap,
        scaledWidth: Int,
        scaledHeight: Int,
        targetWidth: Int,
        targetHeight: Int
    ): Bitmap {
        val resultBitmap = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(resultBitmap)
        
        // 不绘制背景色，保持透明背景
        // canvas.drawColor(_selectedBgColor.value)
        
        // 限制绘制区域为画布大小，超出的部分不显示
        canvas.clipRect(0f, 0f, targetWidth.toFloat(), targetHeight.toFloat())
        
        // 缩放原始图像
        val scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true)
        
        // 计算居中位置
        val left = (targetWidth - scaledWidth) / 2
        val top = (targetHeight - scaledHeight) / 2
        
        // 将缩放后的图像绘制到目标Bitmap的中心
        canvas.drawBitmap(scaledBitmap, left.toFloat(), top.toFloat(), null)
        
        // 如果不需要临时的缩放位图，释放它
        if (scaledBitmap != bitmap) {
            scaledBitmap.recycle()
        }
        
        return resultBitmap
    }
    
    /**
     * 应用选中的规格
     */
    fun applySelectedSpec() {
        // 检查是否已选择规格
        if (_selectedPhotoSpec.value == null) {
            showMessage("请先选择证件照规格", MessageType.WARNING)
            return
        }
        
        viewModelScope.launch {
            val currentSpec = selectedPhotoSpec.value ?: return@launch
            val bitmap = currentBitmap.value ?: return@launch
            
            _isProcessing.value = true
            showMessage("正在应用「${currentSpec.name}」规格，请稍候...", MessageType.INFO)
            
            try {
                // 计算目标尺寸（像素）
                // 假设300DPI的打印分辨率，将毫米转换为像素
                val dpi = _selectedDpi.value
                val mmToInch = 0.0393701f
                
                val targetWidthPixels = (currentSpec.width * mmToInch * dpi).toInt()
                val targetHeightPixels = (currentSpec.height * mmToInch * dpi).toInt()
                
                // 创建调整后的图像
                val result = withContext(Dispatchers.Default) {
                    // 计算缩放比例
                    val originalWidth = bitmap.width
                    val originalHeight = bitmap.height
                    
                    val widthRatio = targetWidthPixels.toFloat() / originalWidth
                    val heightRatio = targetHeightPixels.toFloat() / originalHeight
                    
                    // 选择较小的比例，确保图像完全适合目标尺寸
                    val scaleFactor = minOf(widthRatio, heightRatio)
                    
                    // 计算缩放后的尺寸
                    val scaledWidth = (originalWidth * scaleFactor).toInt()
                    val scaledHeight = (originalHeight * scaleFactor).toInt()
                    
                    // 检查是否需要进行扩展 - 缩放后的尺寸比目标尺寸小5%以上
                    val needsExpansion = scaledWidth < targetWidthPixels * 0.95f || scaledHeight < targetHeightPixels * 0.95f
                    
                    // 初始化TFLite处理器
                    val tfLiteProcessor = TFLiteImageProcessor(context)
                    try {
                        Log.d("EditViewModel", "初始化TFLite处理器")
                        tfLiteProcessor.initialize()
                    } catch (e: Exception) {
                        Log.e("EditViewModel", "TFLite处理器初始化失败: ${e.message}", e)
                    }
                    
                    var resultBitmap: Bitmap
                    
                    // 先缩放图像
                    val scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true)
                    
                    // 使用等比例缩放方法调整大小
                    try {
                        Log.d("EditViewModel", "使用等比例调整图像")
                        // 应用等比例调整
                        val expandedBitmap = tfLiteProcessor.expandImage(scaledBitmap, targetWidthPixels, targetHeightPixels)
                        
                        if (expandedBitmap != null) {
                            Log.d("EditViewModel", "等比例调整成功")
                            resultBitmap = expandedBitmap
                        } else {
                            Log.w("EditViewModel", "等比例调整失败，使用增强型放大算法")
                            // 判断是否需要放大
                            val isUpscaling = targetWidthPixels > bitmap.width * 1.1f || targetHeightPixels > bitmap.height * 1.1f
                            
                            if (isUpscaling) {
                                // 使用增强型放大方法
                                resultBitmap = tfLiteProcessor.superResolutionScaling(
                                    scaledBitmap,
                                    targetWidthPixels,
                                    targetHeightPixels
                                )
                                Log.d("EditViewModel", "应用增强型放大算法成功")
                            } else {
                                resultBitmap = createStandardResizedBitmap(
                                    bitmap,
                                    scaledWidth,
                                    scaledHeight,
                                    targetWidthPixels,
                                    targetHeightPixels
                                )
                            }
                        }
                    } catch (e: Exception) {
                        Log.e("EditViewModel", "等比例调整过程中出错: ${e.message}", e)
                        // 出错时使用标准方法
                        resultBitmap = createStandardResizedBitmap(
                            bitmap,
                            scaledWidth,
                            scaledHeight,
                            targetWidthPixels,
                            targetHeightPixels
                        )
                    }
                    
                    // 释放资源
                    if (scaledBitmap != bitmap) {
                        scaledBitmap.recycle()
                    }
                    tfLiteProcessor.close()
                    
                    resultBitmap
                }
                
                // 更新当前图像和预览图像
                _currentBitmap.postValue(result)
                
                // 将已选择的规格设置为已确认规格
                _actualCanvasSpec.value = currentSpec
                
                // 安全处理bitmap.config - 不使用result.config
                val previewBitmap = result.copy(Bitmap.Config.ARGB_8888, true)
                _previewBitmap.postValue(previewBitmap)
                
                // 关闭预览
                _showPreview.value = false
                
                // 重置变换
                resetGestureTransformation()
                
                showMessage("已成功应用「${currentSpec.name}」规格，尺寸为${currentSpec.width}×${currentSpec.height}mm", MessageType.SUCCESS)
                
            } catch (e: Exception) {
                Log.e("EditViewModel", "Error applying photo spec", e)
                showMessage("应用规格时出错：${e.message}", MessageType.ERROR)
            } finally {
                _isProcessing.value = false
            }
        }
    }
    
    /**
     * 创建标准调整大小的位图
     */
    private fun createStandardResizedBitmap(
        bitmap: Bitmap,
        scaledWidth: Int,
        scaledHeight: Int,
        targetWidthPixels: Int,
        targetHeightPixels: Int
    ): Bitmap {
        // 创建目标大小的空白Bitmap，使用当前背景颜色
        val resultBitmap = Bitmap.createBitmap(
            targetWidthPixels, 
            targetHeightPixels, 
            Bitmap.Config.ARGB_8888
        )
        
        // 创建Canvas，不填充背景颜色
        val canvas = android.graphics.Canvas(resultBitmap)
        // canvas.drawColor(_selectedBgColor.value)
        
        // 限制绘制区域为画布大小，超出的部分不显示
        canvas.clipRect(0, 0, targetWidthPixels, targetHeightPixels)
        
        // 缩放原始图像
        val scaledBitmap = Bitmap.createScaledBitmap(
            bitmap, 
            scaledWidth, 
            scaledHeight, 
            true
        )
        
        // 计算居中位置
        val left = (targetWidthPixels - scaledWidth) / 2
        val top = (targetHeightPixels - scaledHeight) / 2
        
        // 将缩放后的图像绘制到目标Bitmap的中心
        canvas.drawBitmap(scaledBitmap, left.toFloat(), top.toFloat(), null)
        
        // 如果不需要临时的缩放位图，释放它
        if (scaledBitmap != bitmap) {
            scaledBitmap.recycle()
        }
        
        return resultBitmap
    }
    
    /**
     * 加载图片
     */
    fun loadImage(uri: Uri) {
        viewModelScope.launch {
            try {
                _isProcessing.value = true
                
                // 从URI加载位图
                val bitmap = withContext(Dispatchers.IO) {
                    BitmapUtils.getBitmapFromUri(context, uri)
                }
                
                // 保存原始图片用于重置
                originalBitmap = bitmap
                _currentBitmap.value = bitmap
                
                _isProcessing.value = false
            } catch (e: Exception) {
                Log.e("EditViewModel", "加载图片失败: ${e.message}")
                _isProcessing.value = false
                showMessage("图片加载失败", MessageType.ERROR)
            }
        }
    }
    
    /**
     * 从数据库ID加载图片
     */
    fun loadImageFromId(photoId: Long) {
        if (photoRepository == null || photoId <= 0) return
        
        viewModelScope.launch {
            try {
                _isProcessing.value = true
                
                // 从数据库获取照片记录
                val photoRecord = withContext(Dispatchers.IO) {
                    photoRepository.getPhotoById(photoId)
                }
                
                if (photoRecord != null) {
                    // 从文件路径加载位图
                    val bitmap = withContext(Dispatchers.IO) {
                        val file = File(photoRecord.filePath)
                        if (file.exists()) {
                            BitmapUtils.getBitmapFromFile(file)
                        } else {
                            null
                        }
                    }
                    
                    if (bitmap != null) {
                        // 保存原始图片用于重置
                        originalBitmap = bitmap
                        _currentBitmap.value = bitmap
                        showMessage("照片加载成功", MessageType.SUCCESS)
                    } else {
                        showMessage("照片文件不存在或已损坏", MessageType.ERROR)
                    }
                } else {
                    showMessage("找不到指定的照片记录", MessageType.ERROR)
                }
                
                _isProcessing.value = false
            } catch (e: Exception) {
                Log.e("EditViewModel", "根据ID加载图片失败: ${e.message}")
                _isProcessing.value = false
                showMessage("加载图片失败", MessageType.ERROR)
            }
        }
    }
    
    /**
     * 设置当前标签
     */
    fun setActiveTab(tab: EditTab) {
        _activeTab.value = tab
    }
    
    /**
     * 重置所有编辑
     */
    fun resetEdits() {
        viewModelScope.launch {
            _currentBitmap.value = originalBitmap
            _portraitExtracted.value = false
            _selectedBgColors.value = setOf(_selectedBgColor.value)
            _scale.value = 1f
            resetGestureTransformation()
            showMessage("已重置所有参数", MessageType.INFO)
        }
    }
    
    /**
     * 批量保存多个背景颜色的图像
     */
    suspend fun saveMultipleBackgroundImages(): List<Uri> {
        Log.d("EditViewModel", "⚠️⚠️ 开始批量保存图片")
        
        if (!_portraitExtracted.value || portraitWithTransparentBg == null || _selectedBgColors.value.isEmpty()) {
            showMessage("请先抠图并选择至少一种背景颜色", MessageType.ERROR)
            Log.d("EditViewModel", "⚠️⚠️ 批量保存失败 - 未抠图或未选择背景颜色")
            return emptyList()
        }
        
        val results = mutableListOf<Uri>()
        
        try {
            // 设置处理状态
                _isProcessing.value = true
                
            // 记录当前选中的背景颜色，便于后面恢复
            val originalBgColor = _selectedBgColor.value
            
            // 获取选中的背景颜色集合
            val colorsList = _selectedBgColors.value.toList()
            Log.d("EditViewModel", "⚠️⚠️ 准备处理 ${colorsList.size} 个背景颜色: $colorsList")
            
            // 获取当前选中的规格
            val actualSpec = _actualCanvasSpec.value ?: _selectedPhotoSpec.value
            if (actualSpec == null) {
                showMessage("请先选择证件照规格再保存", MessageType.WARNING)
                Log.d("EditViewModel", "⚠️⚠️ 批量保存失败 - 未选择规格")
                return emptyList()
            }
            
            // 计算实际画布尺寸（像素）
            val dpi = _selectedDpi.value
            val mmToInch = 0.0393701f
            val targetWidthPixels = (actualSpec.width * mmToInch * dpi).toInt()
            val targetHeightPixels = (actualSpec.height * mmToInch * dpi).toInt()
            
            Log.d("EditViewModel", "⚠️⚠️ 目标尺寸: ${targetWidthPixels}x${targetHeightPixels}像素，规格: ${actualSpec.name}")
            
            // 使用时间戳作为文件名前缀
            val timestamp = System.currentTimeMillis()
            
            // 确保缩略图目录存在
            val internalThumbDir = File(context.filesDir, "thumbnails")
            if (!internalThumbDir.exists()) {
                internalThumbDir.mkdirs()
            }
            
            // 在IO线程中处理每个颜色
            withContext(Dispatchers.IO) {
                // 获取当前的缩放和偏移信息
                var userScale = _gestureScale.value
                var userOffsetX = _offsetX.value
                var userOffsetY = _offsetY.value
                
                // 获取原始图像的尺寸
                val bitmap = portraitWithTransparentBg!!
                val originalWidth = bitmap.width
                val originalHeight = bitmap.height
                
                // 检测当前缩放和偏移是否会导致空白区域
                val isImageFillsCanvas = checkIfImageFillsCanvas(
                    originalWidth, originalHeight,
                    userScale, userOffsetX, userOffsetY,
                    targetWidthPixels, targetHeightPixels
                )
                
                // 如果检测到空白区域，自动调整缩放
                if (!isImageFillsCanvas) {
                    Log.d("EditViewModel", "⚠️⚠️ 检测到可能存在空白区域，自动调整缩放比例")
                    
                    // 计算填充画布所需的最小缩放比例
                    val minScaleX = targetWidthPixels.toFloat() / originalWidth
                    val minScaleY = targetHeightPixels.toFloat() / originalHeight
                    val fillScale = maxOf(minScaleX, minScaleY) * 1.05f // 额外添加5%的缩放确保覆盖
                    
                    // 调整缩放和偏移
                    userScale = maxOf(userScale, fillScale)
                    // 居中图像
                    userOffsetX = 0f
                    userOffsetY = 0f
                    
                    Log.d("EditViewModel", "⚠️⚠️ 已自动调整缩放比例: $userScale (原始: ${_gestureScale.value}), 并居中图像")
                }
                
                Log.d("EditViewModel", "⚠️⚠️ 最终导出参数 - 缩放: $userScale, 偏移: X=$userOffsetX, Y=$userOffsetY")
                
                // 对每个选中的颜色进行处理 - 使用同步处理每个颜色，避免并发问题
                colorsList.forEachIndexed { index, color ->
                    try {
                        Log.d("EditViewModel", "⚠️⚠️ 开始处理背景颜色 #${index+1}/${colorsList.size}: ${String.format("#%06X", 0xFFFFFF and color)}")
                        
                        // 1. 创建一个透明背景的位图，与当前画布尺寸相同
                        val resultBitmap = Bitmap.createBitmap(targetWidthPixels, targetHeightPixels, Bitmap.Config.ARGB_8888)
                        val canvas = Canvas(resultBitmap)
                        
                        // 2. 填充背景色
                        canvas.drawColor(color)
                        
                        // 3. 先创建带透明背景的人像，并应用当前的缩放和偏移
                        val bitmapToDraw = portraitWithTransparentBg!!
                        
                        // 计算裁剪区域 - 使用调整后的缩放和偏移
                        val displayCenterX = originalWidth / 2f
                        val displayCenterY = originalHeight / 2f
                        
                        // 计算缩放后的图像相对于显示区域中心的偏移
                        val effectiveCenterX = (displayCenterX - userOffsetX / userScale)
                        val effectiveCenterY = (displayCenterY - userOffsetY / userScale)
                        
                        // 目标区域在原图中的尺寸，需要考虑用户的缩放因素
                        val cropWidthInOriginal = targetWidthPixels / userScale
                        val cropHeightInOriginal = targetHeightPixels / userScale
                        
                        // 计算在原图上的裁剪区域边界
                        val cropLeftInOriginal = (effectiveCenterX - cropWidthInOriginal / 2).toInt().coerceAtLeast(0)
                        val cropTopInOriginal = (effectiveCenterY - cropHeightInOriginal / 2).toInt().coerceAtLeast(0)
                        val cropRightInOriginal = (cropLeftInOriginal + cropWidthInOriginal).toInt().coerceAtMost(originalWidth)
                        val cropBottomInOriginal = (cropTopInOriginal + cropHeightInOriginal).toInt().coerceAtMost(originalHeight)
                        
                        // 实际可以裁剪的区域大小
                        val effectiveCropWidth = cropRightInOriginal - cropLeftInOriginal
                        val effectiveCropHeight = cropBottomInOriginal - cropTopInOriginal
                        
                        Log.d("EditViewModel", "⚠️⚠️ 裁剪区域: Left=$cropLeftInOriginal, Top=$cropTopInOriginal, " +
                              "Right=$cropRightInOriginal, Bottom=$cropBottomInOriginal")
                        Log.d("EditViewModel", "⚠️⚠️ 实际裁剪尺寸: ${effectiveCropWidth}x${effectiveCropHeight}")
                        
                        // 直接从原图裁剪，然后缩放绘制到结果图像上
                        val croppedBitmap = try {
                            Bitmap.createBitmap(
                                bitmapToDraw,
                                cropLeftInOriginal,
                                cropTopInOriginal,
                                effectiveCropWidth,
                                effectiveCropHeight
                            )
                        } catch (e: Exception) {
                            Log.e("EditViewModel", "⚠️⚠️ 裁剪失败，使用原图: ${e.message}")
                            bitmapToDraw
                        }
                        
                        // 将裁剪后的图像缩放到目标大小
                        val finalCroppedBitmap = Bitmap.createScaledBitmap(
                            croppedBitmap,
                            targetWidthPixels,
                            targetHeightPixels,
                            true
                        )
                        
                        // 使用SRC_OVER模式绘制人像（保留透明度）
                        val paint = Paint().apply {
                            isAntiAlias = true
                            isFilterBitmap = true
                        }
                        
                        // 直接将缩放后的裁剪图像绘制到画布上
                        canvas.drawBitmap(finalCroppedBitmap, 0f, 0f, paint)
                        
                        // 回收临时创建的位图
                        if (croppedBitmap != bitmapToDraw) {
                            croppedBitmap.recycle()
                        }
                        if (finalCroppedBitmap != croppedBitmap) {
                            finalCroppedBitmap.recycle()
                        }
                        
                        Log.d("EditViewModel", "⚠️⚠️ 成功生成背景色 #${index+1} 的图像")
                        
                        // 6. 生成文件名
                        val colorHex = String.format("#%06X", 0xFFFFFF and color)
                        val fileName = "ID_${actualSpec.name.replace(" ", "_")}_${timestamp}_bg${index+1}_${colorHex}.png"
                        Log.d("EditViewModel", "⚠️⚠️ 准备保存文件: $fileName")
                        
                        // 7. 保存图片到外部存储
                        val uri = cn.edu.baiyunu.myapplication.utils.StorageHelper.saveImageToExternalStorage(
                            context,
                            resultBitmap,
                            fileName
                        )
                        
                        if (uri != null) {
                            // 获取文件的实际路径
                            val filePath = uri.toString()
                            
                            // 创建和保存缩略图
                            val thumbnailBitmap = StorageHelper.createThumbnail(resultBitmap, 300, 300)
                            val thumbnailFileName = "thumb_${fileName}"
                            val thumbnailFile = File(internalThumbDir, thumbnailFileName)
                            
                            try {
                                // 直接保存缩略图到内部存储，不使用ContentResolver
                                FileOutputStream(thumbnailFile).use { outputStream ->
                                    thumbnailBitmap.compress(Bitmap.CompressFormat.JPEG, 85, outputStream)
                                    outputStream.flush()
                                }
                                Log.d("EditViewModel", "⚠️⚠️ 缩略图已保存到内部存储: ${thumbnailFile.absolutePath}")
                                
                                // 缩略图路径使用file://格式的内部存储路径
                                val thumbnailPath = thumbnailFile.absolutePath
                                
                                Log.d("EditViewModel", "⚠️⚠️ 原始文件路径: $filePath")
                                Log.d("EditViewModel", "⚠️⚠️ 缩略图路径: $thumbnailPath")
                                
                                // 保存到数据库，包含规格信息和分辨率
                                saveToDatabase(
                                    filePath, 
                                    thumbnailPath,
                                    backgroundColor = getColorName(color),
                                    specName = actualSpec.name,
                                    width = targetWidthPixels,
                                    height = targetHeightPixels
                                )
                                
                                // 添加到结果列表
                                results.add(uri)
                                Log.d("EditViewModel", "⚠️⚠️ 成功保存图片 #${index+1}: $uri")
                                
                                // 释放缩略图资源
                                thumbnailBitmap.recycle()
                            } catch (e: Exception) {
                                Log.e("EditViewModel", "⚠️⚠️ 保存缩略图失败: ${e.message}", e)
                            }
                        } else {
                            Log.e("EditViewModel", "⚠️⚠️ 保存图片 #${index+1} 失败")
                        }
                        
                        // 回收不再需要的位图
                        resultBitmap.recycle()
                        
                        // 在每个图片处理之间添加一点延迟，避免资源争用
                        delay(50)
                        
                    } catch (e: Exception) {
                        Log.e("EditViewModel", "⚠️⚠️ 处理背景色 #${index+1} 时出错: ${e.message}", e)
                        e.printStackTrace()
                        // 继续处理下一个颜色
                    }
                }
            }
            
            // 恢复原来的背景色
            withContext(Dispatchers.Main) {
                if (portraitWithTransparentBg != null && !portraitWithTransparentBg!!.isRecycled) {
                    changeBackgroundColor(originalBgColor)
                }
            }
            
            // 显示结果
            if (results.isNotEmpty()) {
                withContext(Dispatchers.Main) {
                    showMessage("已保存 ${results.size} 张不同背景的图片到手机相册", MessageType.SUCCESS)
                }
                Log.d("EditViewModel", "⚠️⚠️ 批量保存成功: ${results.size} 张图片")
            } else {
                withContext(Dispatchers.Main) {
                    showMessage("图片保存失败", MessageType.ERROR)
                }
                Log.d("EditViewModel", "⚠️⚠️ 批量保存失败: 0 张图片")
            }
            
            return results
            
        } catch (e: Exception) {
            Log.e("EditViewModel", "⚠️⚠️ 批量保存图片失败: ${e.message}", e)
            e.printStackTrace()
            withContext(Dispatchers.Main) {
                showMessage("批量保存图片失败: ${e.message}", MessageType.ERROR)
            }
            return emptyList()
        } finally {
            _isProcessing.value = false
        }
    }
    
    /**
     * 检查存储权限
     */
    private fun checkStoragePermission(): Boolean {
        // 使用StorageHelper确保存储目录存在
        return StorageHelper.ensureStorageDirectoryExists(context)
    }
    
    /**
     * 保存单张图片并导航到结果页面
     */
    fun saveSingleImageAndNavigate(onNavigateToResult: () -> Unit) {
        // 权限检查
        if (!checkStoragePermission()) {
            showMessage("需要存储权限才能保存图片", MessageType.ERROR)
            return
        }
        
        viewModelScope.launch {
            try {
                val uri = saveEditedImage()
                if (uri != null) {
                    Log.d("EditViewModel", "单张图片保存成功，uri: $uri，准备导航到结果页面")
                    // 延迟一下再导航，确保消息显示
                    delay(500)
                    // 导航到结果页面
                    onNavigateToResult()
                } else {
                    Log.d("EditViewModel", "单张图片保存失败，未获取到URI")
                }
            } catch (e: Exception) {
                Log.e("EditViewModel", "保存过程中发生错误: ${e.message}", e)
                showMessage("保存失败: ${e.message}", MessageType.ERROR)
            }
        }
    }
    
    /**
     * 批量保存图片并导航到结果页面
     */
    fun saveBatchImagesAndNavigate(onNavigateToResult: () -> Unit) {
        // 权限检查
        if (!checkStoragePermission()) {
            showMessage("需要存储权限才能保存图片", MessageType.ERROR)
            return
        }
        
        viewModelScope.launch {
            try {
                val results = saveMultipleBackgroundImages()
                Log.d("EditViewModel", "批量保存完成，结果数量: ${results.size}")
                if (results.isNotEmpty()) {
                    Log.d("EditViewModel", "批量保存成功，准备导航到结果页面")
                    // 延迟一下再导航，确保消息显示
                    delay(500)
                    // 导航到结果页面
                    onNavigateToResult()
                }
            } catch (e: Exception) {
                Log.e("EditViewModel", "批量保存过程中发生错误: ${e.message}", e)
                showMessage("批量保存失败: ${e.message}", MessageType.ERROR)
            }
        }
    }
    
    /**
     * 保存编辑后的图像（单张）
     * 只保存实际画布区域的图像（绿色框内区域）
     */
    suspend fun saveEditedImage(): Uri? {
        val bitmap = _currentBitmap.value ?: return null
        val actualSpec = _actualCanvasSpec.value ?: _selectedPhotoSpec.value
        
        try {
            Log.d("EditViewModel", "开始保存图片 - saveEditedImage()")
            // 设置处理状态
            _isProcessing.value = true
            
            // 检查是否有选择规格
            if (actualSpec == null) {
                showMessage("请先选择证件照规格再保存", MessageType.WARNING)
                Log.d("EditViewModel", "保存失败 - 未选择规格")
                return null
            }
            
            // 计算实际画布尺寸（像素）
            val dpi = _selectedDpi.value
            val mmToInch = 0.0393701f
            val targetWidthPixels = (actualSpec.width * mmToInch * dpi).toInt()
            val targetHeightPixels = (actualSpec.height * mmToInch * dpi).toInt()
            
            Log.d("EditViewModel", "目标尺寸: ${targetWidthPixels}x${targetHeightPixels}像素，规格: ${actualSpec.name}")
            
            // 计算当前参考画布尺寸（如果存在）
            val referenceSpec = _referenceCanvasSpec.value
            val canvasRatio = if (referenceSpec != null && actualSpec != null) {
                referenceSpec.width / actualSpec.width
            } else {
                1.5f // 默认参考画布是实际画布的1.5倍
            }
            
            // 计算参考画布大小（像素）
            val referenceWidthPixels = if (referenceSpec != null) {
                (referenceSpec.width * mmToInch * dpi).toInt()
            } else {
                targetWidthPixels
            }
            val referenceHeightPixels = if (referenceSpec != null) {
                (referenceSpec.height * mmToInch * dpi).toInt()
            } else {
                targetHeightPixels
            }
            
            // 计算实际画布相对于参考画布的中心位置偏移
            val canvasOffsetX = (referenceWidthPixels - targetWidthPixels) / 2
            val canvasOffsetY = (referenceHeightPixels - targetHeightPixels) / 2
            
            // 记录缩放和偏移的关系
            Log.d("EditViewModel", "参考画布比例: ${canvasRatio}x, 参考画布像素: ${referenceWidthPixels}x${referenceHeightPixels}, 实际画布像素: ${targetWidthPixels}x${targetHeightPixels}")
            
            // 调整大小和裁剪（如果需要）
            val finalBitmap = withContext(Dispatchers.Default) {
                try {
                    // ===== 完全重写图像裁剪逻辑 =====
                    Log.d("EditViewModel", "开始使用新的裁剪算法处理图像")
                    
                    // 1. 获取用户的缩放和偏移信息
                    val userScale = _gestureScale.value
                    val userOffsetX = _offsetX.value
                    val userOffsetY = _offsetY.value
                    
                    Log.d("EditViewModel", "用户缩放: $userScale, 用户偏移: X=$userOffsetX, Y=$userOffsetY")
                    
                    // 2. 将原图以用户当前的缩放比例缩放
                    val originalWidth = bitmap.width
                    val originalHeight = bitmap.height
                    val scaledWidth = (originalWidth * userScale).toInt()
                    val scaledHeight = (originalHeight * userScale).toInt()
                    val scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true)
                    
                    // 3. 创建目标输出图像，大小为证件照规格的像素尺寸
                    val resultBitmap = Bitmap.createBitmap(targetWidthPixels, targetHeightPixels, Bitmap.Config.ARGB_8888)
                    val canvas = Canvas(resultBitmap)
                    // 不自动填充背景色，保持透明背景
                    // canvas.drawColor(_selectedBgColor.value)
                    
                    // 限制绘制区域为画布大小，超出的部分不显示
                    canvas.clipRect(0f, 0f, targetWidthPixels.toFloat(), targetHeightPixels.toFloat())
                    
                    // 4. 计算原始图像中实际显示在屏幕中心的那部分内容的位置
                    // 注意这里的关键是把用户在可视界面中看到的裁剪区域(绿色框内)精确地提取出来
                    
                    // 先计算显示区域（屏幕）的中心点
                    val displayCenterX = originalWidth / 2f
                    val displayCenterY = originalHeight / 2f
                    
                    // 再计算缩放后的图像相对于显示区域中心的偏移
                    // 注意：偏移值是相对于缩放后的图像的，所以需要考虑缩放
                    // 如果用户向右拖动图像(offsetX为正)，实际裁剪区域应该向左移
                    val effectiveCenterX = (displayCenterX - userOffsetX / userScale)
                    val effectiveCenterY = (displayCenterY - userOffsetY / userScale)
                    
                    // 5. 根据中心点和目标尺寸计算在原图中需要裁剪的区域
                    // 目标区域在原图中的尺寸，需要考虑用户的缩放因素
                    val cropWidthInOriginal = targetWidthPixels / userScale
                    val cropHeightInOriginal = targetHeightPixels / userScale
                    
                    // 计算在原图上的裁剪区域边界
                    val cropLeftInOriginal = (effectiveCenterX - cropWidthInOriginal / 2).toInt().coerceAtLeast(0)
                    val cropTopInOriginal = (effectiveCenterY - cropHeightInOriginal / 2).toInt().coerceAtLeast(0)
                    val cropRightInOriginal = (cropLeftInOriginal + cropWidthInOriginal).toInt().coerceAtMost(originalWidth)
                    val cropBottomInOriginal = (cropTopInOriginal + cropHeightInOriginal).toInt().coerceAtMost(originalHeight)
                    
                    // 6. 实际可以裁剪的区域大小
                    val effectiveCropWidth = cropRightInOriginal - cropLeftInOriginal
                    val effectiveCropHeight = cropBottomInOriginal - cropTopInOriginal
                    
                    // 记录日志，方便调试
                    Log.d("EditViewModel", "原图尺寸: ${originalWidth}x${originalHeight}")
                    Log.d("EditViewModel", "目标尺寸: ${targetWidthPixels}x${targetHeightPixels}")
                    Log.d("EditViewModel", "裁剪区域(原图坐标系): Left=$cropLeftInOriginal, Top=$cropTopInOriginal, " +
                          "Right=$cropRightInOriginal, Bottom=$cropBottomInOriginal")
                    Log.d("EditViewModel", "实际裁剪尺寸: ${effectiveCropWidth}x${effectiveCropHeight}")
                    
                    // 7. 计算裁剪区域在目标图像上的位置 (居中)
                    val dstLeft = (targetWidthPixels - effectiveCropWidth * userScale) / 2
                    val dstTop = (targetHeightPixels - effectiveCropHeight * userScale) / 2
                    val dstRight = dstLeft + effectiveCropWidth * userScale
                    val dstBottom = dstTop + effectiveCropHeight * userScale
                    
                    // 8. 直接从原图裁剪，然后缩放绘制到结果图像上
                    val srcRect = android.graphics.Rect(
                        cropLeftInOriginal,
                        cropTopInOriginal,
                        cropRightInOriginal,
                        cropBottomInOriginal
                    )
                    
                    val dstRect = android.graphics.RectF(
                        dstLeft,
                        dstTop,
                        dstRight,
                        dstBottom
                    )
                    
                    // 9. 绘制裁剪后的图像到结果图像上
                    Log.d("EditViewModel", "绘制区域: Left=$dstLeft, Top=$dstTop, Right=$dstRight, Bottom=$dstBottom")
                    
                    // 使用原图直接绘制，跳过中间的scaledBitmap
                    val paint = android.graphics.Paint().apply {
                        isFilterBitmap = true
                        isAntiAlias = true
                    }
                    
                    // 严格裁剪，只绘制实际画布(绿色框)内的内容
                    // 这里不使用drawBitmap的缩放绘制，改为先裁剪原图，再精确绘制
                    val croppedBitmap = Bitmap.createBitmap(
                        bitmap,
                        cropLeftInOriginal,
                        cropTopInOriginal,
                        effectiveCropWidth,
                        effectiveCropHeight
                    )
                    
                    // 将裁剪后的图像缩放到目标大小
                    val finalCroppedBitmap = Bitmap.createScaledBitmap(
                        croppedBitmap,
                        targetWidthPixels,
                        targetHeightPixels,
                        true
                    )
                    
                    // 直接将缩放后的裁剪图像绘制到画布中心
                    canvas.drawBitmap(finalCroppedBitmap, 0f, 0f, paint)
                    
                    // 回收临时创建的位图
                    if (croppedBitmap != bitmap) {
                        croppedBitmap.recycle()
                    }
                    if (finalCroppedBitmap != croppedBitmap) {
                        finalCroppedBitmap.recycle()
                    }
                    
                    resultBitmap
                } catch (e: Exception) {
                    Log.e("EditViewModel", "处理图像失败: ${e.message}", e)
                    e.printStackTrace()
                    
                    // 回退到标准调整方法
                    createStandardResizedBitmap(bitmap, bitmap.width, bitmap.height, targetWidthPixels, targetHeightPixels)
                }
            }
            
            // 使用StorageHelper保存图片
            val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(System.currentTimeMillis())
            val fileName = "ID_${actualSpec.name.replace(" ", "_")}_${timestamp}.png"
            
            Log.d("EditViewModel", "保存文件名: $fileName")
            
            // 使用StorageHelper保存图片到外部存储
            val uri = cn.edu.baiyunu.myapplication.utils.StorageHelper.saveImageToExternalStorage(
                context,
                finalBitmap,
                fileName
            )
            
            if (uri != null) {
                // 获取文件的实际路径（用于数据库存储）
                val filePath = uri.toString()
                
                // 构建缩略图路径 - 使用应用内部存储
                val thumbnailFileName = "thumb_$fileName"
                val internalThumbDir = File(context.filesDir, "thumbnails")
                val thumbnailFile = File(internalThumbDir, thumbnailFileName)
                val thumbnailPath = thumbnailFile.absolutePath
                
                Log.d("EditViewModel", "原始文件路径: $filePath")
                Log.d("EditViewModel", "缩略图路径: $thumbnailPath")
                
                // 保存到数据库，包含规格信息和分辨率
                saveToDatabase(
                    filePath, 
                    thumbnailPath,
                    backgroundColor = getColorName(_selectedBgColor.value),
                    specName = actualSpec.name,
                    width = targetWidthPixels,
                    height = targetHeightPixels
                )
                
                if (finalBitmap != bitmap) {
                    finalBitmap.recycle()
                }
                
                withContext(Dispatchers.Main) {
                    showMessage("图片已保存到手机相册，尺寸: ${targetWidthPixels}x${targetHeightPixels}", MessageType.SUCCESS)
                }
                Log.d("EditViewModel", "照片保存成功: $filePath, 规格: ${actualSpec.name}, 尺寸: ${targetWidthPixels}x${targetHeightPixels}")
            } else {
                withContext(Dispatchers.Main) {
                    showMessage("保存图片失败: 无法创建文件", MessageType.ERROR)
                }
                Log.e("EditViewModel", "保存失败: 无法创建文件URI")
            }
            
            return uri
        } catch (e: Exception) {
            Log.e("EditViewModel", "保存图片失败: ${e.message}", e)
            withContext(Dispatchers.Main) {
                showMessage("保存图片失败: ${e.message}", MessageType.ERROR)
            }
            return null
        } finally {
            _isProcessing.value = false
        }
    }
    
    /**
     * 保存照片记录到数据库
     */
    private fun saveToDatabase(
        filePath: String, 
        thumbnailPath: String, 
        backgroundColor: String = getColorName(_selectedBgColor.value),
        specName: String = _selectedPhotoSpec.value?.name ?: "未知规格",
        width: Int = _currentBitmap.value?.width ?: 0,
        height: Int = _currentBitmap.value?.height ?: 0
    ) {
        // 如果没有提供仓库，则不保存到数据库
        if (photoRepository == null) return
        
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val photoRecord = cn.edu.baiyunu.myapplication.data.db.entity.PhotoRecord(
                    filePath = filePath,
                    thumbnailPath = thumbnailPath,
                    specType = specName,
                    backgroundColor = backgroundColor,
                    createdAt = System.currentTimeMillis(),
                    width = width,
                    height = height,
                    isAiOptimized = _portraitExtracted.value
                )
                
                photoRepository.savePhotoRecord(photoRecord)
                Log.d("EditViewModel", "照片记录已保存到数据库")
            } catch (e: Exception) {
                Log.e("EditViewModel", "保存照片记录到数据库失败: ${e.message}")
            }
        }
    }
    
    /**
     * 获取颜色名称
     */
    private fun getColorName(colorValue: Int): String {
        return when (colorValue) {
            0xFF0078D7.toInt() -> "蓝色"
            0xFFE81123.toInt() -> "红色"
            0xFF107C10.toInt() -> "绿色"
            android.graphics.Color.WHITE -> "白色"
            android.graphics.Color.BLACK -> "黑色"
            else -> "自定义"
        }
    }
    
    /**
     * 更新裁剪比例并应用
     */
    fun updateScale(scale: Float) {
        _scale.value = scale
        applyScaling()
    }
    
    /**
     * 应用裁剪缩放
     */
    private fun applyScaling() {
        val bitmap = if (_portraitExtracted.value && portraitWithTransparentBg != null) {
            // 如果已经抠图，就在抠好的图上应用缩放
            modNetProcessor.changeBackground(portraitWithTransparentBg!!, _selectedBgColor.value)
        } else {
            // 否则在原图上应用缩放
            originalBitmap
        } ?: return
        
        viewModelScope.launch {
            try {
                _isProcessing.value = true
                
                // 在IO线程中处理图像缩放
                val scaled = withContext(Dispatchers.IO) {
                    applyScalingToBitmap(bitmap)
                }
                
                // 更新UI
                _currentBitmap.value = scaled
                _isProcessing.value = false
                
            } catch (e: Exception) {
                Log.e("EditViewModel", "应用缩放失败: ${e.message}")
                _isProcessing.value = false
                showMessage("缩放处理失败", MessageType.ERROR)
            }
        }
    }
    
    /**
     * 对bitmap应用缩放
     */
    private fun applyScalingToBitmap(bitmap: Bitmap): Bitmap {
                    if (_scale.value == 1f) {
            return bitmap
        }
                        
                        // 计算新的缩放尺寸
        val originalWidth = bitmap.width
        val originalHeight = bitmap.height
                        val scaledWidth = (originalWidth * _scale.value).toInt()
                        val scaledHeight = (originalHeight * _scale.value).toInt()
                        
        // 创建新的缩放后的位图
                        val scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true)
                        
                        // 创建与原始尺寸相同的最终位图
                        val resultBitmap = Bitmap.createBitmap(originalWidth, originalHeight, Bitmap.Config.ARGB_8888)
                        val canvas = Canvas(resultBitmap)
        
        // 设置背景颜色（如果是抠图结果，使用当前选择的颜色；否则使用白色）
        if (_portraitExtracted.value) {
            canvas.drawColor(_selectedBgColor.value)
        } else {
            canvas.drawColor(Color.WHITE)
        }
                        
                        // 将缩放后的位图绘制在居中位置
                        val left = (originalWidth - scaledWidth) / 2f
                        val top = (originalHeight - scaledHeight) / 2f
                        canvas.drawBitmap(scaledBitmap, left, top, null)
                        
                        // 回收临时位图
                        if (scaledBitmap != bitmap) {
                            scaledBitmap.recycle()
                        }
                        
        return resultBitmap
    }
    
    /**
     * 重置裁剪
     */
    fun resetScale() {
        _scale.value = 1f
        // 重置后立即应用
        applyScaling()
    }
    
    /**
     * 更新手势缩放
     */
    fun updateGestureScale(scale: Float) {
        _gestureScale.value = scale.coerceIn(0.1f, 3f)
        checkImageBounds()
    }
    
    /**
     * 更新位移
     */
    fun updateOffset(x: Float, y: Float) {
        _offsetX.value = x
        _offsetY.value = y
        checkImageBounds()
    }
    
    /**
     * 重置手势变换
     */
    fun resetGestureTransformation() {
        _gestureScale.value = 1f
        _offsetX.value = 0f
        _offsetY.value = 0f
    }
    
    /**
     * 执行人像抠图
     */
    fun extractPortrait() {
        // 始终使用原始图像进行抠图，避免累积残留
        val bitmap = originalBitmap ?: return
        
        viewModelScope.launch {
            try {
                _isProcessing.value = true
                
                // 在IO线程中执行抠图
                val result = withContext(Dispatchers.IO) {
                    // 1. 生成蒙版
                    val mask = modNetProcessor.processImage(bitmap)
                    if (mask == null) {
                        showMessage("抠图失败", MessageType.ERROR)
                        return@withContext null
                    }
                    
                    // 保存蒙版供后续使用
                    portraitMask = mask
                    
                    // 2. 应用蒙版，提取带透明背景的人像
                    val portrait = modNetProcessor.applyMask(bitmap, mask)
                    
                    // 保存带透明背景的人像供后续使用
                    portraitWithTransparentBg = portrait
                    
                    // 3. 更换为当前选定的背景色
                    modNetProcessor.changeBackground(portrait, _selectedBgColor.value)
                }
                
                // 更新UI
                if (result != null) {
                    _currentBitmap.value = result
                    _portraitExtracted.value = true
                    // 初始化选中的背景色
                    _selectedBgColors.value = setOf(_selectedBgColor.value)
                }
                
                _isProcessing.value = false
                showMessage("人像抠图完成", MessageType.SUCCESS)
                
            } catch (e: Exception) {
                Log.e("EditViewModel", "抠图失败: ${e.message}")
                _isProcessing.value = false
                showMessage("抠图处理失败", MessageType.ERROR)
            }
        }
    }
    
    /**
     * 更改抠图背景颜色
     */
    fun changeBackgroundColor(color: Int) {
        if (!_portraitExtracted.value || portraitWithTransparentBg == null) {
            return
        }
        
        viewModelScope.launch {
            try {
                _isProcessing.value = true
                
                _selectedBgColor.value = color
                
                // 在IO线程中处理图像
                val result = withContext(Dispatchers.IO) {
                    modNetProcessor.changeBackground(portraitWithTransparentBg!!, color)
                }
                
                // 更新UI
                _currentBitmap.value = result
                _isProcessing.value = false
                
            } catch (e: Exception) {
                Log.e("EditViewModel", "更换背景失败: ${e.message}")
                _isProcessing.value = false
                showMessage("更换背景失败", MessageType.ERROR)
            }
        }
    }
    
    /**
     * 添加或移除选中的背景颜色
     */
    fun toggleBackgroundColor(color: Int) {
        val currentColors = _selectedBgColors.value.toMutableSet()
        
        if (currentColors.contains(color)) {
            // 如果已包含该颜色且不是唯一选中的颜色，则移除
            if (currentColors.size > 1) {
                currentColors.remove(color)
            }
        } else {
            // 否则添加该颜色
            currentColors.add(color)
        }
        
        _selectedBgColors.value = currentColors
        
        // 如果更改了当前显示的颜色，需要更新显示
        if (color == _selectedBgColor.value && !currentColors.contains(color)) {
            // 选一个新的颜色作为当前显示的颜色
            val newColor = currentColors.first()
            changeBackgroundColor(newColor)
        }
    }
    
    /**
     * 判断颜色是否被选中
     */
    fun isColorSelected(color: Int): Boolean {
        return _selectedBgColors.value.contains(color)
    }
    
    override fun onCleared() {
        super.onCleared()
        // 释放MODNet资源
        modNetProcessor.close()
    }
    
    /**
     * ViewModel工厂
     */
    class Factory(
        private val context: Context,
        private val photoRepository: cn.edu.baiyunu.myapplication.data.repository.PhotoRepository? = null
    ) : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            if (modelClass.isAssignableFrom(EditViewModel::class.java)) {
                return EditViewModel(context, photoRepository) as T
            }
            throw IllegalArgumentException("Unknown ViewModel class")
        }
    }
    
    /**
     * 切换预览显示
     */
    fun togglePreview() {
        if (!_showPreview.value) {
            // 显示预览前，先重新生成预览图以确保是最新状态
            generatePreview(true) // 显示预览窗口
        } else {
            // 隐藏预览
            _showPreview.value = false
        }
        
        Log.d("EditViewModel", "切换预览显示: ${_showPreview.value}")
    }
    
    /**
     * 设置DPI值
     */
    fun setDpi(dpi: Float) {
        _selectedDpi.value = dpi
        // 如果已经选择了规格，重新生成预览
        if (_selectedPhotoSpec.value != null) {
            generatePreview()
        }
    }
    
    /**
     * 根据ID选择证件照规格
     */
    fun selectSpecById(specId: String) {
        val spec = _availablePhotoSpecs.value.find { it.id == specId }
        if (spec != null) {
            selectPhotoSpec(spec)
            // 自动切换到规格选择标签
            _activeTab.value = EditTab.SPECS
        } else {
            Log.w("EditViewModel", "找不到ID为 $specId 的规格")
        }
    }
    
    /**
     * 自适应模式枚举
     */
    enum class CanvasAdaptMode {
        FIT,    // 适应模式：保持比例，可能会有留白
        FILL    // 填充模式：保持比例，填满画布，可能会裁剪部分图像
    }
    
    /**
     * 一键自适应画布
     * 将当前图片自动调整为适合画布的大小
     * @param mode 适应模式，FIT为适应（保持全图可见），FILL为填充（撑满画布）
     */
    fun applyAutoAdaptToCanvas(mode: CanvasAdaptMode = CanvasAdaptMode.FIT) {
        val bitmap = _currentBitmap.value ?: return
        val spec = _selectedPhotoSpec.value
        
        viewModelScope.launch {
            try {
                _isProcessing.value = true
                
                val modeText = if (mode == CanvasAdaptMode.FIT) "适应" else "填充"
                showMessage("正在${modeText}模式下处理图像，请稍候...", MessageType.INFO)
                
                // 如果没有选择规格，使用当前图片尺寸
                val targetWidth: Int
                val targetHeight: Int
                
                if (spec != null) {
                    // 计算目标尺寸（像素）
                    val dpi = _selectedDpi.value
                    val mmToInch = 0.0393701f
                    targetWidth = (spec.width * mmToInch * dpi).toInt()
                    targetHeight = (spec.height * mmToInch * dpi).toInt()
                } else {
                    // 使用当前图片尺寸
                    targetWidth = bitmap.width
                    targetHeight = bitmap.height
                }
                
                // 使用TFLite处理器进行自适应处理
                val tfLiteProcessor = TFLiteImageProcessor(context)
                
                try {
                    val result = withContext(Dispatchers.IO) {
                        Log.d("EditViewModel", "初始化TFLite处理器，适应模式: $mode")
                        tfLiteProcessor.initialize()
                        
                        // 根据模式选择不同的处理方法
                        when (mode) {
                            CanvasAdaptMode.FIT -> {
                                // 适应模式：保持图像完整，可能有留白
                                tfLiteProcessor.adaptToCanvas(bitmap, targetWidth, targetHeight, _selectedBgColor.value)
                            }
                            CanvasAdaptMode.FILL -> {
                                // 填充模式：填满画布，可能裁剪部分图像
                                tfLiteProcessor.fillCanvas(bitmap, targetWidth, targetHeight, _selectedBgColor.value)
                            }
                        }
                    }
                    
                    if (result != null) {
                        // 更新当前图像
                        _currentBitmap.value = result
                        
                        val modeText = if (mode == CanvasAdaptMode.FIT) "适应" else "填充"
                        showMessage("已完成${modeText}式自适应调整", MessageType.SUCCESS)
                    } else {
                        showMessage("自适应调整图片失败", MessageType.ERROR)
                    }
                } finally {
                    tfLiteProcessor.close()
                }
                
            } catch (e: Exception) {
                Log.e("EditViewModel", "自适应调整图片失败: ${e.message}", e)
                showMessage("自适应调整图片失败: ${e.message}", MessageType.ERROR)
            } finally {
                _isProcessing.value = false
            }
        }
    }
    
    /**
     * 一键美颜/增强功能
     * 使用TFLite进行图像增强
     */
    fun applyBeauty() {
        val bitmap = _currentBitmap.value ?: return
        
        viewModelScope.launch {
            try {
                _isProcessing.value = true
                showMessage("正在进行图像美化增强处理，请稍候...", MessageType.INFO)
                
                // 使用TFLite处理器进行美颜处理
                val tfLiteProcessor = TFLiteImageProcessor(context)
                
                try {
                    val result = withContext(Dispatchers.IO) {
                        Log.d("EditViewModel", "初始化TFLite处理器，应用美颜效果")
                        tfLiteProcessor.initialize()
                        
                        // 应用基本美颜效果
                        tfLiteProcessor.enhanceImage(bitmap)
                    }
                    
                    if (result != null) {
                        // 更新当前图像
                        _currentBitmap.value = result
                        showMessage("已完成一键美颜/增强，图像质量已提升", MessageType.SUCCESS)
                    } else {
                        showMessage("美颜处理失败", MessageType.ERROR)
                    }
                } finally {
                    tfLiteProcessor.close()
                }
                
            } catch (e: Exception) {
                Log.e("EditViewModel", "美颜处理失败: ${e.message}", e)
                showMessage("美颜处理失败: ${e.message}", MessageType.ERROR)
            } finally {
                _isProcessing.value = false
            }
        }
    }
    
    /**
     * 切换全屏模式
     */
    fun toggleFullScreenMode() {
        _isFullScreenMode.value = !_isFullScreenMode.value
        checkImageBounds()
    }
    
    /**
     * 检查图片是否超出画布边界
     */
    fun checkImageBounds() {
        viewModelScope.launch {
            val bitmap = _currentBitmap.value ?: return@launch
            val actualSpec = _actualCanvasSpec.value ?: return@launch
            val scale = _gestureScale.value
            val offsetX = _offsetX.value
            val offsetY = _offsetY.value
            
            // 计算图片的实际显示尺寸
            val scaledImageWidth = bitmap.width * scale
            val scaledImageHeight = bitmap.height * scale
            
            // 计算画布尺寸（像素）
            val mmToInch = 0.0393701f
            val dpi = _selectedDpi.value
            val canvasWidthPx = (actualSpec.width * mmToInch * dpi).toInt()
            val canvasHeightPx = (actualSpec.height * mmToInch * dpi).toInt()
            
            // 获取参考画布规格和比例
            val referenceSpec = _referenceCanvasSpec.value
            val canvasRatio = if (referenceSpec != null) {
                referenceSpec.width / actualSpec.width
            } else {
                1.5f
            }
            
            // 检查图片是否超出画布边界
            // 使用图片边缘位置来判断是否有部分超出画布
            val imageLeft = (bitmap.width / 2) - (scaledImageWidth / 2) + offsetX
            val imageRight = (bitmap.width / 2) + (scaledImageWidth / 2) + offsetX
            val imageTop = (bitmap.height / 2) - (scaledImageHeight / 2) + offsetY
            val imageBottom = (bitmap.height / 2) + (scaledImageHeight / 2) + offsetY
            
            // 记录图像位置信息
            Log.d("EditViewModel", "图像位置: Left=$imageLeft, Top=$imageTop, Right=$imageRight, Bottom=$imageBottom")
            Log.d("EditViewModel", "图像缩放: $scale, 画布比例: $canvasRatio")
            
            // 画布中心位置（假定为编辑区域的中心）
            val canvasLeft = (bitmap.width - canvasWidthPx) / 2
            val canvasRight = (bitmap.width + canvasWidthPx) / 2
            val canvasTop = (bitmap.height - canvasHeightPx) / 2
            val canvasBottom = (bitmap.height + canvasHeightPx) / 2
            
            // 记录画布位置信息
            Log.d("EditViewModel", "画布位置: Left=$canvasLeft, Top=$canvasTop, Right=$canvasRight, Bottom=$canvasBottom")
            
            // 判断是否超出
            // 图像应该完全覆盖画布，否则认为有超出或空白区域
            val isFullyCovered = imageLeft <= canvasLeft && 
                                imageRight >= canvasRight && 
                                imageTop <= canvasTop && 
                                imageBottom >= canvasBottom

            _isImageExceedCanvas.value = !isFullyCovered // 如果图像不能完全覆盖画布，则显示警告
        }
    }
    
    /**
     * 检查图像是否完全填充画布（没有空白区域）
     */
    private fun checkIfImageFillsCanvas(
        originalWidth: Int, originalHeight: Int,
        scale: Float, offsetX: Float, offsetY: Float,
        targetWidth: Int, targetHeight: Int
    ): Boolean {
        // 计算缩放后的图像尺寸
        val scaledWidth = originalWidth * scale
        val scaledHeight = originalHeight * scale
        
        // 计算图像中心位置（考虑偏移）
        val imageCenterX = scaledWidth / 2 + offsetX
        val imageCenterY = scaledHeight / 2 + offsetY
        
        // 计算目标画布的中心
        val canvasCenterX = targetWidth / 2f
        val canvasCenterY = targetHeight / 2f
        
        // 计算图像边缘到画布边缘的距离
        val leftEdge = canvasCenterX - imageCenterX + scaledWidth / 2
        val rightEdge = imageCenterX + scaledWidth / 2 - canvasCenterX
        val topEdge = canvasCenterY - imageCenterY + scaledHeight / 2
        val bottomEdge = imageCenterY + scaledHeight / 2 - canvasCenterY
        
        // 检查是否图像完全覆盖画布（没有边缘超出）
        val hasEmptySpace = leftEdge < 0 || rightEdge < 0 || 
                           topEdge < 0 || bottomEdge < 0
        
        Log.d("EditViewModel", "图像覆盖检查 - 缩放: $scale, 偏移: ($offsetX, $offsetY), " +
              "缩放后尺寸: ${scaledWidth}x${scaledHeight}, 目标尺寸: ${targetWidth}x${targetHeight}, " +
              "有空白区域: $hasEmptySpace")
        
        return !hasEmptySpace
    }
}

/**
 * 预设枚举
 */
enum class EditPreset {
    NATURAL,
    PROFESSIONAL,
    SOFT
} 